

package com.saas.ability.core.base.thread;

import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.saas.ability.core.base.util.ThreadUtils;

public final class DumpThreadRejectedHandler implements RejectedExecutionHandler {

    private final static Logger LOGGER = LoggerFactory.getLogger(DumpThreadRejectedHandler.class);

    private volatile boolean dumping = false;

    private final String name;
    
    private final ThreadPoolConfig poolConfig;

    private final int rejectedPolicy;

    public DumpThreadRejectedHandler(String name,ThreadPoolConfig poolConfig) {
    	this.name = name;
        this.poolConfig = poolConfig;
        this.rejectedPolicy = poolConfig.getRejectedPolicy();
    }

    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        LOGGER.warn("one task rejected, poolConfig={}, poolInfo={}", poolConfig, ThreadUtils.getPoolInfo(e));
        if (!dumping) {
            dumping = true;
        }

        if (rejectedPolicy == ThreadPoolConfig.REJECTED_POLICY_ABORT) {
            throw new RejectedExecutionException("one task rejected, pool=" + name);
        } else if (rejectedPolicy == ThreadPoolConfig.REJECTED_POLICY_CALLER_RUNS) {
            if (!e.isShutdown()) {
                r.run();
            }
        }
    }

}

